//Well it looks like we forgot this vital piece of the program
//... Lovely - Strog
#ifndef STATEMACHINE_H
#define STATEMACHINE_H

#include <cassert>
#include <string>

#include "State.h"

template <class EntityType>
class StateMachine
{
private:
	EntityType* pOwner;
	State<EntityType>* pCurrentState;
	State<EntityType>* pPreviousState;
	//I have no idea if we need this last pointer, but here it is just in case
	State<EntityType>* pGlobalState;

public:
	StateMachine(EntityType* owner):  pOwner(owner),
									  pCurrentState(NULL),
									  pPreviousState(NULL),
									  pGlobalState(NULL)
	{}

	virtual ~StateMachine() {}

	//use these methods to initialize the FSM
	//In case anyone's wondering, FSM means Finite State Machine. Not Flying Spaghetti Monster
	void SetCurrentState(State<EntityType>* s) {pCurrentState = s; }
	void SetGlobalState(State<EntityType>* s) {pGlobalState = s; }
	void SetPreviousState(State<EntityType>* s) {pPreviousState = s; }

	//call this to update the FSM
	void Update()const
	{
		if(pGlobalState)	pGlobalState->Execute(pOwner);
		if(pCurrentState)	pCurrentState->Execute(pOwner);

	}


	void ChangeState(State<EntityType>* pNewState)
	{
		assert(pNewState &&
			"<StateMachine::ChangeState>: trying to change to NULL state");
		//keep record of previous state
		pPreviousState = pCurrentState;

		//call the exit method of the existing state
		pCurrentState->Exit(pOwner); // This was causing the master to exit constantly after every execute

		//change state to new state
		pCurrentState = pNewState;

		//call entry method of the new state
		pCurrentState->Enter(pOwner);
	}

	//change back to the previous state, duh
	void RevertToPreviousState()
	{
		ChangeState(pPreviousState);
	}

	//returns true if the current state's type is equal to the type of the
	//class passed as a parameter.
	//Strog: "Uh... okay :) "
	
	//bool isInState(const State<EntityType>& st)const
	//{
	//	return typeid(*pCurrentState) == typeid(st);
	//}
	//CUT AND SLASH AND MAIM AND BURN, THIS CODE SHALL BE AS BUCKLANDS! -K13

	bool  isInState(const State<EntityType>& st)const
  {
    if (typeid(*pCurrentState) == typeid(st)) return true;
    return false;
  }

	//simple get functions
	//I'm tempted to add "get" in the function name, but I have a feeling that
	//someone, namely me, will forget to correct the name when he's copying and pasting
	//more code - Strog
	State<EntityType>*  CurrentState()  const{return pCurrentState;}
    State<EntityType>*  GlobalState()   const{return pGlobalState;}
    State<EntityType>*  PreviousState() const{return pPreviousState;}

};


#endif